/*
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

#ifndef _DRAWAREA_H
#define _DRAWAREA_H

#include <iostream>
#include <limits>
#include <cmath>

#include <QWidget>
#include <QPainter>
#include <QPen>
#include <QPoint>
#include <QMatrix>
#include <QColor>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QRectF>
#include <QPainterPath>
#include <QString>
#include <QHelpEvent>
#include <QFont>

#include "../gType.h"
#include "../transformation.h"
#include "gPath.h"
#include "controlPoints.h"
#include "pointToolTip.h"
#include "drawMenu.h"
#include "dialogs.h"

class drawArea: public QWidget{
	
	Q_OBJECT
	
	private:
		static const int FOCUS_BORDER = 10;
		static const int POINT_DISTANCE_X = 5;
		static const int POINT_DISTANCE_Y = 15;
	
		static const Qt::BrushStyle POINT_BRUSH_DOUBLECLICK_STYLE = Qt::SolidPattern;
		static const Qt::GlobalColor POINT_BRUSH_DOUBLECLICK_COLOR = Qt::yellow;
		static const Qt::PenStyle POINT_PEN_DOUBLECLICK_STYLE = Qt::SolidLine;
		static const Qt::GlobalColor POINT_PEN_DOUBLECLICK_COLOR = Qt::red;
		static const Qt::GlobalColor LINE_PEN_DOUBLECLICK_COLOR = Qt::white;
	
		static const Qt::BrushStyle POINT_BRUSH_MOUSEOVER_STYLE = Qt::SolidPattern;
		static const Qt::GlobalColor POINT_BRUSH_MOUSEOVER_COLOR = Qt::yellow;
		static const Qt::PenStyle POINT_PEN_MOUSEOVER_STYLE = Qt::SolidLine;
		static const Qt::GlobalColor POINT_PEN_MOUSEOVER_COLOR = Qt::yellow;
		
		static const Qt::PenStyle MIDDLE_AXIS_STYLE = Qt::DashDotLine;
		
		static const Qt::BrushStyle POINT_BRUSH_STYLE = Qt::SolidPattern;
		static const Qt::GlobalColor POINT_BRUSH_COLOR = Qt::red;
		static const Qt::PenStyle POINT_PEN_STYLE = Qt::SolidLine;
		static const Qt::GlobalColor POINT_PEN_COLOR = Qt::darkRed;
		
		static const Qt::BrushStyle POINT_STYLE = Qt::SolidPattern;
		static const Qt::PenStyle AXIS_STYLE = Qt::DashLine;
		static const Qt::GlobalColor AXIS_COLOR = Qt::darkGray;
		static const Qt::GlobalColor CANVAS_BACKGROUND = Qt::black;
		static const Qt::GlobalColor POINT_COLOR = Qt::darkRed;
		static const Qt::GlobalColor LINE_COLOR = Qt::lightGray;
		static const Qt::GlobalColor MOVE_COLOR = Qt::blue;
		static const Qt::PenStyle LINE_STYLE = Qt::SolidLine;
		static const qreal POINT_SIZE = 3.0;
	
        QRectF clickedRect;
        gObject *previousObject;
		gObjectContainer *container;
		gObjectContainer buffContainer;
		QMatrix transform;
		controlPoints control;
		QPointF buffPoint;
		bool once, distance, numerate, changed;
		transformation logicTransform;
		toolTransformation toolTransform;
		morphTransformation morphTransform;
		listToolTipDialog *listTip;
		//graphics elements (lines, points, etc...)
		gPathCuts cuts;
		gPathMoves moves;
		gPathBuff buffCuts;
			
		float vectorAngle(float , float , float , float );
	
		void setBackground(QPainter &);
		void setFirstTransform();
		void drawAxis(QPainter &);
		void drawBuff(QPainter &);
		void setStyles(QPainter &, Qt::BrushStyle, Qt::GlobalColor, Qt::PenStyle, Qt::GlobalColor);
		void highligth(QPainter &, gObject &, gTypeGo &, const QPointF &);
		void pointOnMouseOver(QPainter &);
		void pointOnClicked(QPainter &);
		void pointDoubleClicked(QPainter &);
		void drawCircleAxis(QPainter &);
		void drawNumbers(QPainter &);
		void drawPoints(QPainter &);
		void drawMoves(QPainter &);
		void drawCuts(QPainter &);
		void drawArrow(QPainter &);
        void drawHighlight(QPainter &);
	
	protected:
		virtual void paintEvent(QPaintEvent *);
		virtual void keyPressEvent(QKeyEvent *);
		virtual void mouseMoveEvent(QMouseEvent *);
		virtual void mousePressEvent(QMouseEvent *);
		virtual bool event(QEvent *);
		virtual void wheelEvent(QWheelEvent *);
		virtual void mouseReleaseEvent(QMouseEvent *);
		virtual void mouseDoubleClickEvent(QMouseEvent *);
		virtual void contextMenuEvent(QContextMenuEvent *);
		virtual void showEvent(QShowEvent *);
	
	public slots:
		void focus(gObject * = 0, bool = true);
		void mark(gObject * = 0);
		void middle();
		void setDistanceMode();
		void setNumerate();
		void setScale(QPointF &);
		void setChanged(bool);
		void logicTranslate(QPointF &);
		void logicRotate(QPointF &, float);
		void logicFlush();
		void logicRestore();
		void logicTool(float, float, bool, bool);
		bool logicMorph(float, morphTransformation::morphType, bool, bool);
	
	signals:
		void gObjectDoubleClicked(gObject *);
		void gTypeGoClicked(gTypeGo *, const QPointF &);
		void realPosF(QPointF *);
		void scaleChanged();
		void changedSignal(drawArea *);
	
	public:
		drawArea(QWidget *, gObjectContainer *);
		
		const controlPoints &getControl();
		void updateContainer();
		void updateBuffContainer();
		void getScale(QPointF &) const;
		bool getChanged();
		QMatrix getMatrix() const;
		void setMatrix(QMatrix &);
		gObjectContainer *getBuffContainer();

};

#endif
